﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __IMPL_PARSE_REQUEST_IMPL_H__
#define __IMPL_PARSE_REQUEST_IMPL_H__

#include "../tools/head.h"

namespace xos_http
{
    class session;

    class parse_request_impl : public xos_stl::mem_item< xos::release_impl< parse_request_impl >, thread_lock >, 
        public i_parse_request
    {
    public:
        typedef xos::release_impl< parse_request_impl > T;
        enum enumState
        {
            STATE_NEED_MORE_HEAD_DATA,
            STATE_NEED_MORE_BODY_DATA,
            STATE_PROC_SUCCESS,
            STATE_PROC_FAILED
        };

    public:
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //

        static int get_addr( POOL *** pppPool, LIST *** pppList );

    public:
        parse_request_impl();
        ~parse_request_impl();

    public:
        int set_param_property( xos_box::i_property * pProperty );
        int set_path_property( xos_box::i_property * pProperty );
        int set_tag_property( xos_box::i_property * pProperty );
        int set_recv_list( xos_box::i_list * pList );
        int set_body_list( xos_box::i_list * pList );
        int set_cookie_list( xos_box::i_list * pList );
        int set_session( xos_http::i_session ** ppv );
        int set_ssl( bool bSSL );
        int reset();
        // 
        // 返回值定义：
        // 
        // 0  : 成功
        // 1  : 需要更多数据
        // -1 : 出现错误
        // 
        int proc();

    protected:
        xos_box::i_property * m_pParamProperty;
        xos_box::i_property * m_pPathProperty;
        xos_box::i_property * m_pTagProperty;
        xos_box::i_list * m_pRecvList;
        xos_box::i_list * m_pBodyList;
        xos_box::i_list * m_pCookieList;
        session ** m_ppSession;
        enumState m_eState;
        bool m_bSSL;

        // 解析http post body
    protected:
        // 1.解析参数,Content-Type: application/x-www-form-urlencoded，这时先将参数放入HTTP_REQUEST_PARAM中，由parse_params与GET方式的参数一样解析
        // 2.上传文件,Content-Type: multipart/form-data
        int parse_multipart_head( xos_box::i_property * pProperty, xos_box::i_list * pBodyList, xos_box::i_big_buf * pBigBuf, const char * lpszBound, int nBoundLen );
        int parse_multipart_body( xos_box::i_property * pProperty, xos_box::i_list * pBodyList, xos_box::i_big_buf * pBigBuf, const char * lpszBound, int nBoundLen );

        int parse_multipart_body_value( xos_box::i_property * pProperty, xos_box::i_list * pBodyList, xos_box::i_big_buf * pBigBuf, const char * lpszBound, int nBoundLen );
        int parse_multipart_body_file( xos_box::i_property * pProperty, xos_box::i_list * pBodyList, xos_box::i_big_buf * pBigBuf, const char * lpszBound, int nBoundLen );
        int parse_multipart_body_list( xos_box::i_property * pProperty, xos_box::i_list * pBodyList, xos_box::i_big_buf * pBigBuf, const char * lpszBound, int nBoundLen );

        int parse_post_body();
        int application();
        int multipart();

    protected:
        int set_param( const char * lpszName, const char * lpszVal );

        int parse_cmd( char * lpszData, int & nLen, int & nPos );

        int parse_tags( xos_box::i_property * pProperty, char * lpszData, int & nLen, int & nPos );
        int parse_tag( xos_box::i_property * pProperty, char * lpszData, int & nLen, int & nPos );

        // www.cat.com:8080 -> www.cat.com_8080
        int change_host_fmt();

        int parse_url();
        int parse_params();
        int parse_uri();

        int parse_http_head();
        int parse_http_body();

        int parse_session_tag();
        int parse_cookie_tag();

        int init_data();

    public:
        int init();
        int term();

    };

} // xos_http

#endif // __IMPL_PARSE_REQUEST_IMPL_H__
